package com.example.scan.controller;


import com.example.scan.entity.ScanRecord;
import com.example.scan.service.IGameScoreInfoService;
import com.example.scan.service.IScanRecordService;
import com.example.scan.util.ReflectionUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author txm
 * @since 2020-08-04
 */
@RestController
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Slf4j
public class ScanRecordController {

    private final IScanRecordService iScanRecordService;
    private final IGameScoreInfoService iGameScoreInfoService;
    private final RestTemplate restTemplate;

    @Value("${com.example.scan.mzfcallbackpath}")
    private String mzfcallbackpath;

    @Value("${com.example.scan.mzfkey}")
    private String mzfkey;
    @Value("${com.example.scan.mzfid}")
    private String mzfid;


    /**
     * 生成二维码
     *
     * @param treeMap
     * @return
     */
    @PostMapping(path = "scan")
    public ResponseEntity scan(@RequestBody TreeMap treeMap, HttpServletRequest httpServletRequest) {
        treeMap.put("id", mzfid);
        //treeMap.put("token", "ywvCXjWLwunECMBpt3yKlf1OB76mGVgW");
        treeMap.put("pay_id", UUID.randomUUID().toString());
        treeMap.put("notify_url", mzfcallbackpath);
        StringBuffer stringBuffer = new StringBuffer();
        treeMap.forEach((o, o2) -> {
            stringBuffer.append("&" + o + "=" + o2);
        });
        String substring = stringBuffer.substring(1);
        String sign = DigestUtils.md5DigestAsHex((substring + mzfkey).getBytes());
        ResponseEntity responseEntity = restTemplate.postForEntity("http://api2.xiuxiu888.com/creat_order?" + substring + "&sign=" + sign, null, String.class);
        Object body = responseEntity.getBody();
        return ResponseEntity.ok(body);
    }

    /**
     * 支付成功后回调即可偶
     *
     * @return
     */
    @PostMapping(path = "scanRollback")
    public ResponseEntity scanRollback(HttpServletRequest httpServletRequest
    ) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, JsonProcessingException {
        Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
        if (StringUtils.isEmpty(parameterMap.get("pay_no")[0])) {
            return ResponseEntity.ok("fail");
        }

        TreeMap treeMap = new TreeMap<>(parameterMap);
        String sign = (String) ((Object[]) treeMap.remove("sign"))[0];
        StringBuffer stringBuffer = new StringBuffer();
        treeMap.forEach((o, o2) -> {
            if (o2 != null) {
                stringBuffer.append("&" + o + "=" + ((Object[]) o2)[0]);
            }
        });
        String substring = stringBuffer.substring(1);
        String sign1 = DigestUtils.md5DigestAsHex((substring + mzfkey).getBytes());
        if (!sign1.equals(sign)) {
            return ResponseEntity.ok("fail");
        }
        //修改数据库
        ScanRecord scanRecord = (ScanRecord) ReflectionUtil.mapToHump(ScanRecord.class, treeMap);
        scanRecord.setSign(sign);

        try {
            addScore(Integer.valueOf(((String[]) treeMap.get("param"))[0]), scanRecord);
        } catch (DuplicateKeyException duplicateKeyException) {
            return ResponseEntity.ok("success");
        }
        return ResponseEntity.ok("success");
    }

    @Transactional
    public void addScore(Integer param, ScanRecord scanRecord) {
        iScanRecordService.save(scanRecord);
        iGameScoreInfoService.updateScoreById(param, scanRecord.getMoney());
//        GameScoreInfo gameScoreInfo = iGameScoreInfoService.getById( param);
//        gameScoreInfo.setScore(gameScoreInfo.getScore().longValue() + scanRecord.getMoney().longValue()*100);
//        iGameScoreInfoService.updateById(gameScoreInfo);
    }
}
